/*
 * font.c
 * This file is part of libgfx
 *
 * Copyright (C) 2012 - Luke Westby & Jon Gautsch
 *
 * libgfx is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * libgfx is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libgfx. If not, see <http://www.gnu.org/licenses/>.
 */

#include "font.h"

void lower_a(int x, int y, int scale) {
	gfx_line(x+2*scale, y+6*scale, x+6*scale, y+6*scale);
	gfx_line(x, y+9*scale, x+6*scale, y+8*scale);
	gfx_line(x, y+12*scale, x+6*scale, y+12*scale);
	gfx_line(x+6, y+6*scale, x+6*scale, y+12*scale);
	gfx_line(x, y+9*scale, x, y+12*scale);
}

void upper_a(int x, int y, int scale) {
	gfx_line(x+1*scale, y, x+5*scale, y);
    gfx_line(x+1*scale, y, x, y+1*scale);
    gfx_line(x+5*scale, y, x+6*scale, y+1*scale);
	gfx_line(x, y+5*scale, x+6*scale, y+5*scale);
	gfx_line(x, y+1*scale, x, y+12*scale);
	gfx_line(x+6*scale, y+1*scale, x+6*scale, y+12*scale);
}

void lower_b(int x, int y, int scale) {
	gfx_line(x, y+1*scale, x, y+11*scale);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+11*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
}

void upper_b(int x, int y, int scale) {
	gfx_line(x, y+1*scale, x, y+11*scale);
	gfx_line(x+6*scale, y+1*scale, x+6*scale, y+5*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+11*scale);
	gfx_line(x, y, x+5*scale, y);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
}

void lower_c(int x, int y, int scale) {
	gfx_line(x+1*scale, y+5*scale, x+6*scale, y+5*scale);
	gfx_line(x+1*scale, y+12*scale, x+6*scale, y+12*scale);
	gfx_line(x, y+6*scale, x, y+11*scale);
}

void upper_c(int x, int y, int scale) {
	gfx_line(x+1*scale, y, x+6*scale, y);
    gfx_line(x+1*scale, y, x, y+1*scale);
    gfx_line(x, y+11*scale, x+1*scale, y+12*scale);
	gfx_line(x+1*scale, y+12*scale, x+6*scale, y+12*scale);
	gfx_line(x, y+1*scale, x, y+11*scale);
}

void lower_d(int x, int y, int scale) {
	gfx_line(x+6*scale, y+1*scale, x+6*scale, y+11*scale);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x, y+7*scale, x, y+11*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
}	

void upper_d(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
	gfx_line(x+1*scale, y, x+5*scale, y);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
	gfx_line(x+6*scale, y+1*scale, x+6*scale, y+11*scale);
}

void lower_e(int x, int y, int scale) {
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+1*scale, y+9*scale, x+5*scale, y+9*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
	gfx_line(x, y+6*scale, x, y+11*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+8*scale);
}

void upper_e(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
    gfx_line(x, y, x+1*scale, y);
    gfx_line(x, y+6*scale, x+1*scale, y+6*scale);
    gfx_line(x, y+12*scale, x+1*scale, y+12*scale);
	gfx_line(x+1*scale, y, x+6*scale, y);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+1*scale, y+12*scale, x+6*scale, y+12*scale);
}

void lower_f(int x, int y, int scale) {
	gfx_line(x+2*scale, y+1*scale, x+2*scale, y+12*scale);
	gfx_line(x, y+5*scale, x+6*scale, y+5*scale);
	gfx_line(x+3*scale, y, x+6*scale, y);
}

void upper_f(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
	gfx_line(x, y, x+6*scale, y);
	gfx_line(x, y+6*scale, x+5*scale, y+6*scale);
}

void lower_g(int x, int y, int scale) {
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+1*scale, y+9*scale, x+5*scale, y+9*scale);
	gfx_line(x+1*scale, y+14*scale, x+5*scale, y+14*scale);
	gfx_line(x, y+7*scale, x, y+8*scale);
	gfx_line(x+6*scale, y+6*scale, x+6*scale, y+13*scale);
}

void upper_g(int x, int y, int scale) {
	gfx_line(x+1*scale, y, x+5*scale, y);
	gfx_line(x+3*scale, y+6*scale, x+6*scale, y+6*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
	gfx_line(x, y+1*scale, x, y+11*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+11*scale);
}

void lower_h(int x, int y, int scale) {
	gfx_line(x, y+1*scale, x, y+12*scale);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+12*scale);
}

void upper_h(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
	gfx_line(x+6*scale, y, x+6*scale, y+12*scale);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
}

void lower_i(int x, int y, int scale) {
	gfx_line(x+3*scale, y+5*scale, x+4*scale, y+5*scale);
	gfx_line(x+3*scale, y+4*scale, x+4*scale, y+4*scale);
	gfx_line(x+1*scale, y+7*scale, x+3*scale, y+7*scale);
	gfx_line(x+3*scale, y+8*scale, x+3*scale, y+11*scale);
	gfx_line(x+3*scale, y+12*scale, x+5*scale, y+12*scale);
}

void upper_i(int x, int y, int scale) {
	gfx_line(x, y, x+6*scale, y);
	gfx_line(x+3*scale, y+1*scale, x+3*scale, y+11*scale);
	gfx_line(x, y+12*scale, x+6*scale, y+12*scale);
}

void lower_j(int x, int y, int scale) {
	gfx_line(x+4*scale, y+5*scale, x+5*scale, y+5*scale);
	gfx_line(x+4*scale, y+4*scale, x+5*scale, y+4*scale);
	gfx_line(x+2*scale, y+7*scale, x+4*scale, y+7*scale);
	gfx_line(x+4*scale, y+8*scale, x+4*scale, y+13*scale);
	gfx_line(x+3*scale, y+14*scale, x, y+14*scale);
}

void upper_j(int x, int y, int scale) {
	gfx_line(x, y, x+6*scale, y);
	gfx_line(x+5*scale, y+1*scale, x+5*scale, y+11*scale);
	gfx_line(x, y+12*scale, x+4*scale, y+12*scale);
}

void lower_k(int x, int y, int scale) {
	gfx_line(x, y+1*scale, x, y+12*scale);
	gfx_line(x+1*scale, y+9*scale, x+5*scale, y+6*scale);
	gfx_line(x+1*scale, y+9*scale, x+5*scale, y+12*scale);
}

void upper_k(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
	gfx_line(x+1*scale, y+6*scale, x+6*scale, y+1*scale);
	gfx_line(x+1*scale, y+6*scale, x+6*scale, y+12*scale);
}

void lower_l(int x, int y, int scale) {
	gfx_line(x+3*scale, y+1*scale, x+3*scale, y+11*scale);
	gfx_line(x+4*scale, y+12*scale, x+6*scale, y+12*scale);
	gfx_line(x+1*scale, y+1*scale, x+3*scale, y+1*scale);
}

void upper_l(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
    gfx_line(x, y+12*scale, x+1*scale, y+12*scale);
	gfx_line(x+1*scale, y+12*scale, x+6*scale, y+12*scale);
}

void lower_m(int x, int y, int scale) {
	gfx_line(x, y+6*scale, x, y+12*scale);
	gfx_line(x+3*scale, y+6*scale, x+3*scale, y+10*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+12*scale);
	gfx_line(x, y+6*scale, x+2*scale, y+6*scale);
	gfx_line(x+4*scale, y+6*scale, x+5*scale, y+6*scale);
}

void upper_m(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
	gfx_line(x+6*scale, y, x+6*scale, y+12*scale);
	gfx_line(x, y, x+3*scale, y+6*scale);
	gfx_line(x+3*scale, y+6*scale, x+6*scale, y);
}

void lower_n(int x, int y, int scale) {
	gfx_line(x, y+6*scale, x, y+12*scale);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+12*scale);
}

void upper_n(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
	gfx_line(x, y, x+6*scale, y+12*scale);
	gfx_line(x+6*scale, y, x+6*scale, y+12*scale);
}

void lower_o(int x, int y, int scale) {
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x, y+7*scale, x, y+11*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+11*scale);
}

void upper_o(int x, int y, int scale) {
	gfx_line(x+1*scale, y, x+5*scale, y);
    gfx_line(x+1*scale, y, x, y+1*scale);
    gfx_line(x+5*scale, y, x+6*scale, y+1*scale);
    gfx_line(x, y+11*scale, x+1*scale, y+12*scale);
    gfx_line(x+5*scale, y+12*scale, x+6*scale, y+11*scale);
	gfx_line(x, y+1*scale, x, y+11*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
	gfx_line(x+6*scale, y+1*scale, x+6*scale, y+11*scale);
}	

void lower_p(int x, int y, int scale) {
	gfx_line(x, y+6*scale, x, y+14*scale);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+1*scale, y+11*scale, x+5*scale, y+11*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+10*scale);
}

void upper_p(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
	gfx_line(x+1*scale, y, x+5*scale, y);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+6*scale, y+1*scale, x+6*scale, y+5*scale);
}

void lower_q(int x, int y, int scale) {
	gfx_line(x+6*scale, y+6*scale, x+6*scale, y+14*scale);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+1*scale, y+11*scale, x+5*scale, y+11*scale);
	gfx_line(x, y+7*scale, x, y+10*scale);
}

void upper_q(int x, int y, int scale) {
	gfx_line(x+1*scale, y, x+5*scale, y);
	gfx_line(x, y+1*scale, x, y+11*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
	gfx_line(x+6*scale, y+1*scale, x+6*scale, y+11*scale);
	gfx_line(x+4*scale, y+10*scale, x+6*scale, y+13*scale);
}

void lower_r(int x, int y, int scale) {
	gfx_line(x+1*scale, y+6*scale, x+6*scale, y+6*scale);
	gfx_line(x, y+7*scale, x, y+12*scale);
}

void upper_r(int x, int y, int scale) {
	gfx_line(x, y, x, y+12*scale);
	gfx_line(x, y, x+5*scale, y);
    gfx_line(x+5*scale, y, x+6*scale, y+1*scale);
    gfx_line(x+5*scale, y+6*scale, x+6*scale, y+5*scale);
	gfx_line(x, y+6*scale, x+5*scale, y+6*scale);
	gfx_line(x+6*scale, y+1*scale, x+6*scale, y+5*scale);
	gfx_line(x+4*scale, y+6*scale, x+6*scale, y+12*scale);
}

void lower_s(int x, int y, int scale) {
	gfx_line(x+1*scale, y+6*scale, x+6*scale, y+6*scale);
	gfx_line(x+1*scale, y+9*scale, x+5*scale, y+9*scale);
	gfx_line(x, y+12*scale, x+5*scale, y+12*scale);
	gfx_line(x, y+7*scale, x, y+9*scale);
	gfx_line(x+6*scale, y+9*scale, x+6*scale, y+12*scale);
}

void upper_s(int x, int y, int scale) {
    gfx_line(x+1*scale, y, x, y+1*scale);
    gfx_line(x, y+1*scale, x, y+5*scale);
    gfx_line(x, y+5*scale, x+1*scale, y+6*scale);
	gfx_line(x+6*scale, y+7*scale, x+6*scale, y+11*scale);
    gfx_line(x+6*scale, y+7*scale, x+5*scale, y+6*scale);
	gfx_line(x+1*scale, y, x+5*scale, y);
	gfx_line(x+1*scale, y+6*scale, x+5*scale, y+6*scale);
    gfx_line(x+5*scale, y+12*scale, x+6*scale, y+11*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
}

void lower_t(int x, int y, int scale) {
	gfx_line(x+2*scale, y+1*scale, x+2*scale, y+11*scale);
	gfx_line(x, y+4*scale, x+6*scale, y+4*scale);
	gfx_line(x+3*scale, y+12*scale, x+6*scale, y+12*scale);
}

void upper_t(int x, int y, int scale) {
	gfx_line(x, y, x+6*scale, y);
    gfx_line(x+3*scale, y, x+3*scale, y+1*scale);
	gfx_line(x+3*scale, y+1*scale, x+3*scale, y+12*scale);
}

void lower_u(int x, int y, int scale) {
	gfx_line(x, y+6*scale, x, y+11*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
	gfx_line(x+6*scale, y+6*scale, x+6*scale, y+12*scale);
}

void upper_u(int x, int y, int scale) {
	gfx_line(x, y, x, y+11*scale);
	gfx_line(x+1*scale, y+12*scale, x+5*scale, y+12*scale);
	gfx_line(x+6*scale, y, x+6*scale, y+12*scale);
}	

void lower_v(int x, int y, int scale) {
	gfx_line(x, y+6*scale, x+3*scale, y+12*scale);
	gfx_line(x+3*scale, y+12*scale, x+5*scale, y+6*scale);
}

void upper_v(int x, int y, int scale) {
	gfx_line(x, y, x+3*scale, y+12*scale);
	gfx_line(x+6*scale, y, x+3*scale, y+12*scale);
}

void lower_w(int x, int y, int scale) {
	gfx_line(x, y+6*scale, x+2*scale, y+12*scale);
	gfx_line(x+2*scale, y+12*scale, x+3*scale, y+8*scale);
	gfx_line(x+3*scale, y+8*scale, x+5*scale, y+12*scale);
	gfx_line(x+5*scale, y+12*scale, x+6*scale, y+6*scale);
}

void upper_w(int x, int y, int scale) {
	gfx_line(x, y, x+2*scale, y+12*scale);
	gfx_line(x+2*scale, y+12*scale, x+3*scale, y+3*scale);
	gfx_line(x+3*scale, y+3*scale, x+5*scale, y+12*scale);
	gfx_line(x+5*scale, y+12*scale, x+6*scale, y);
}

void lower_x(int x, int y, int scale) {
	gfx_line(x, y+6*scale, x+6*scale, y+12*scale);
	gfx_line(x+6*scale, y+6*scale, x, y+12*scale);
}

void upper_x(int x, int y, int scale) {
	gfx_line(x, y, x+6*scale, y+12*scale);
	gfx_line(x+6*scale, y, x, y+12*scale);
}

void lower_y(int x, int y, int scale) {
	gfx_line(x, y+6*scale, x+3*scale, y+11*scale);
	gfx_line(x+6*scale, y+6*scale, x+2*scale, y+14*scale);
	gfx_line(x, y+14*scale, x+2*scale, y+14*scale);
}

void upper_y(int x, int y, int scale) {
	gfx_line(x, y, x+3*scale, y+6*scale);
	gfx_line(x+3*scale, y+6*scale, x+6*scale, y);
	gfx_line(x+3*scale, y+7*scale, x+3*scale, y+12*scale);
}

void lower_z(int x, int y, int scale) {
	gfx_line(x, y+6*scale, x+6*scale, y+6*scale);
	gfx_line(x+6*scale, y+6*scale, x, y+12*scale);
	gfx_line(x, y+12*scale, x+6*scale, y+12*scale);
}

void upper_z(int x, int y, int scale) {
	gfx_line(x, y, x+6*scale, y);
	gfx_line(x+6*scale, y, x, y+12*scale);
	gfx_line(x, y+12*scale, x+6*scale, y+12*scale);	
}

void (*ch[52]) (int x, int y, int scale) = {
	upper_a, upper_b, upper_c, upper_d, upper_e, upper_f, upper_g, upper_h,
	upper_i, upper_j, upper_k, upper_l, upper_m, upper_n, upper_o, upper_p,
	upper_q, upper_r, upper_s, upper_t, upper_u, upper_v, upper_w, upper_x,
	upper_y, upper_z, lower_a, lower_b, lower_c, lower_d, lower_e, lower_f,
	lower_g, lower_h, lower_i, lower_j, lower_k, lower_l, lower_m, lower_n,
	lower_o, lower_p, lower_q, lower_r, lower_s, lower_t, lower_u, lower_v, 
	lower_w, lower_x, lower_y, lower_z
};

void word(int x, int y, char *word, int scale) {
	int i, len, val;
	len = strlen(word);
	
	for(i = 0; i < len; i++) {
		val = word[i];
		if(val == 32) continue;
		val -= 65;
		if(val > 25) val -= 6;
		(*ch[val])(x + i*(9*scale), y, scale);
	}
}

void letter(int x, int y, char letter, int scale) {
    int i, val;
    
    val = letter;
    if(val == 32) return;
    val -= 65;
    if(val > 25) val -= 6;
    (*ch[val])(x, y, scale);
}
